// internal/service/user_service.go
package service

import (
	"errors"
	"strings"

	"golang.org/x/crypto/bcrypt"

	"github.com/jfastfiler/internal/dao"
	"github.com/jfastfiler/internal/model"
)

type UserService struct {
	userDAO  *dao.UserDAO
	auditDAO *dao.AuditDAO
}

func NewUserService(userDAO *dao.UserDAO, auditDAO *dao.AuditDAO) *UserService {
	return &UserService{
		userDAO:  userDAO,
		auditDAO: auditDAO,
	}
}

type CreateUserRequest struct {
	Username   string `json:"username" binding:"required,min=3,max=50"`
	Password   string `json:"password" binding:"required,min=6,max=100"`
	Email      string `json:"email" binding:"required,email"`
	RealName   string `json:"real_name" binding:"required"`
	Department string `json:"department"`
	Role       string `json:"role" binding:"required,oneof=admin user auditor"`
	Phone      string `json:"phone"`
}

type UpdateUserRequest struct {
	Email      string `json:"email" binding:"required,email"`
	RealName   string `json:"real_name" binding:"required"`
	Department string `json:"department"`
	Role       string `json:"role" binding:"required,oneof=admin user auditor"`
	Status     int    `json:"status" binding:"oneof=0 1 2"`
	Phone      string `json:"phone"`
}

type UserProfile struct {
	ID         int    `json:"id"`
	Username   string `json:"username"`
	Email      string `json:"email"`
	RealName   string `json:"real_name"`
	Department string `json:"department"`
	Role       string `json:"role"`
	Phone      string `json:"phone"`
	Avatar     string `json:"avatar"`
	LastLogin  string `json:"last_login"`
	LoginCount int    `json:"login_count"`
	CreatedAt  string `json:"created_at"`
}

func (s *UserService) CreateUser(req *CreateUserRequest, createdBy int) error {
	// 检查用户名是否已存在
	_, err := s.userDAO.GetByUsername(req.Username)
	if err == nil {
		return errors.New("用户名已存在")
	}

	// 检查邮箱是否已存在
	_, err = s.userDAO.GetByEmail(req.Email)
	if err == nil {
		return errors.New("邮箱已存在")
	}

	// 加密密码
	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
	if err != nil {
		return errors.New("密码加密失败")
	}

	user := &model.User{
		Username:     req.Username,
		PasswordHash: string(hashedPassword),
		Email:        req.Email,
		RealName:     req.RealName,
		Department:   req.Department,
		Role:         req.Role,
		Phone:        req.Phone,
		Status:       1, // 默认启用
		CreatedBy:    createdBy,
	}

	if err := s.userDAO.Create(user); err != nil {
		return err
	}

	s.auditDAO.Create(&model.AuditLog{
		UserID:  createdBy,
		Action:  "create_user",
		Details: "创建用户: " + req.Username + " 角色: " + req.Role,
		Status:  "success",
	})

	return nil
}

func (s *UserService) UpdateUser(userID int, req *UpdateUserRequest, updatedBy int) error {
	user, err := s.userDAO.GetByID(userID)
	if err != nil {
		return errors.New("用户不存在")
	}

	// 检查邮箱是否被其他用户使用
	if user.Email != req.Email {
		existingUser, err := s.userDAO.GetByEmail(req.Email)
		if err == nil && existingUser.ID != userID {
			return errors.New("邮箱已被其他用户使用")
		}
	}

	user.Email = req.Email
	user.RealName = req.RealName
	user.Department = req.Department
	user.Role = req.Role
	user.Status = req.Status
	user.Phone = req.Phone

	if err := s.userDAO.Update(user); err != nil {
		return err
	}

	s.auditDAO.Create(&model.AuditLog{
		UserID:  updatedBy,
		Action:  "update_user",
		Details: "更新用户: " + user.Username + " 状态: " + s.getStatusText(req.Status),
		Status:  "success",
	})

	return nil
}

func (s *UserService) DeleteUser(userID int, deletedBy int) error {
	user, err := s.userDAO.GetByID(userID)
	if err != nil {
		return errors.New("用户不存在")
	}

	// 不能删除自己
	if userID == deletedBy {
		return errors.New("不能删除自己的账户")
	}

	if err := s.userDAO.Delete(userID); err != nil {
		return err
	}

	s.auditDAO.Create(&model.AuditLog{
		UserID:  deletedBy,
		Action:  "delete_user",
		Details: "删除用户: " + user.Username,
		Status:  "success",
	})

	return nil
}

func (s *UserService) ListUsers(params *dao.UserQueryParams) ([]model.User, int64, error) {
	return s.userDAO.List(params)
}

func (s *UserService) GetUser(userID int) (*model.User, error) {
	return s.userDAO.GetByID(userID)
}

func (s *UserService) GetUserProfile(userID int) (*UserProfile, error) {
	user, err := s.userDAO.GetByID(userID)
	if err != nil {
		return nil, err
	}

	return &UserProfile{
		ID:         user.ID,
		Username:   user.Username,
		Email:      user.Email,
		RealName:   user.RealName,
		Department: user.Department,
		Role:       user.Role,
		Phone:      user.Phone,
		Avatar:     user.Avatar,
		LastLogin:  user.LastLogin.Format("2006-01-02 15:04:05"),
		LoginCount: user.LoginCount,
		CreatedAt:  user.CreatedAt.Format("2006-01-02 15:04:05"),
	}, nil
}

func (s *UserService) UpdateUserProfile(userID int, updates map[string]interface{}) error {
	user, err := s.userDAO.GetByID(userID)
	if err != nil {
		return errors.New("用户不存在")
	}

	// 更新允许修改的字段
	if email, ok := updates["email"].(string); ok && email != "" {
		// 检查邮箱是否被其他用户使用
		if user.Email != email {
			existingUser, err := s.userDAO.GetByEmail(email)
			if err == nil && existingUser.ID != userID {
				return errors.New("邮箱已被其他用户使用")
			}
			user.Email = email
		}
	}

	if realName, ok := updates["real_name"].(string); ok {
		user.RealName = realName
	}

	if department, ok := updates["department"].(string); ok {
		user.Department = department
	}

	if phone, ok := updates["phone"].(string); ok {
		user.Phone = phone
	}

	if avatar, ok := updates["avatar"].(string); ok {
		user.Avatar = avatar
	}

	return s.userDAO.Update(user)
}

func (s *UserService) ChangePassword(userID int, oldPassword, newPassword string) error {
	user, err := s.userDAO.GetByID(userID)
	if err != nil {
		return errors.New("用户不存在")
	}

	// 验证旧密码
	err = bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(oldPassword))
	if err != nil {
		return errors.New("原密码错误")
	}

	// 加密新密码
	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost)
	if err != nil {
		return errors.New("密码加密失败")
	}

	user.PasswordHash = string(hashedPassword)
	return s.userDAO.Update(user)
}

func (s *UserService) ResetPassword(userID int, newPassword string, resetBy int) error {
	user, err := s.userDAO.GetByID(userID)
	if err != nil {
		return errors.New("用户不存在")
	}

	// 加密新密码
	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost)
	if err != nil {
		return errors.New("密码加密失败")
	}

	user.PasswordHash = string(hashedPassword)
	
	if err := s.userDAO.Update(user); err != nil {
		return err
	}

	s.auditDAO.Create(&model.AuditLog{
		UserID:  resetBy,
		Action:  "reset_password",
		Details: "重置用户密码: " + user.Username,
		Status:  "success",
	})

	return nil
}

func (s *UserService) GetUserStatistics() (*dao.UserStatistics, error) {
	return s.userDAO.GetStatistics()
}

func (s *UserService) SearchUsers(keyword string, page, pageSize int) ([]model.User, int64, error) {
	params := &dao.UserQueryParams{
		Page:     page,
		PageSize: pageSize,
	}

	// 如果有关键词，搜索用户名、邮箱、真实姓名
	if keyword != "" {
		if strings.Contains(keyword, "@") {
			params.Email = keyword
		} else {
			params.Username = keyword
			params.RealName = keyword
		}
	}

	return s.userDAO.List(params)
}

func (s *UserService) getStatusText(status int) string {
	switch status {
	case 0:
		return "禁用"
	case 1:
		return "正常"
	case 2:
		return "锁定"
	default:
		return "未知"
	}
}